<!DOCTYPE html>
<html>
<head>
<!--
	Copyright (c) 2015-2018 Jean-Marc VIGLINO, 
	released under CeCILL-B (french BSD like) licence: http://www.cecill.info/
-->
	<title>ol-ext: Geoportail layer</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

	<meta name="description" content="Geoportail layer for ol" />
	<meta name="keywords" content="ol, openlayers, layer, source, geoportail" />

	<!-- jQuery -->
	<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.0.min.js"></script>

	<!-- Openlayers -->
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@latest/ol.css" />
  <script type="text/javascript" src="https://cdn.jsdelivr.net/npm/ol@latest/dist/ol.js"></script>
	<script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL,Object.assign"></script>
	
	<!-- ol-ext -->
  <link rel="stylesheet" href="../../dist/ol-ext.css" />
  <script type="text/javascript" src="../../dist/ol-ext.js"></script>
  <!-- Pointer events polyfill for old browsers, see https://caniuse.com/#feat=pointer -->
  <script src="https://unpkg.com/elm-pep"></script>

  <!-- filesaver-js -->
	<script type="text/javascript" src="https://cdn.rawgit.com/eligrey/FileSaver.js/aa9f4e0e/FileSaver.min.js"></script>

	<link rel="stylesheet" href="../style.css" />
  <style>
    button {
      margin: .5em;
    }
    .result {
      max-width: 100%;
      width: 30em;
      box-sizing: border-box;
      overflow: hidden;
      display: block;
      margin: 0;
    }
    pre {
      margin: 0;
      background-color: #fff;
      width: 100%;
      overflow: auto;
      user-select: all;
    }
    .result ul {
      background-color: #fff;
      border: 1px solid #369;
      display: table;
      cursor: pointer;
      padding: 0;
      margin: 0;
    }
    .result li {
      padding: 0 1em;
    }
    .result li:hover {
      background-color: rgb(51, 102, 153, .3);
    }
    select optgroup {
      color: #fff; 
      background-color: #369
    }
    select option {
      color: #333;
      background: #fff;
    }

  </style>
</head>
<body >
	<a href="https://github.com/Viglino/ol-ext" class="icss-github-corner"><i></i></a>

	<a href="../../index.html">
		<h1>ol-ext: Geoportail layer</h1>
	</a>
	<div class="info">
    <p>
      <b>ol/source/Geoportail</b> is IGN's <a href="https://www.geoportail.gouv.fr/">Géoportail</a> WMTS source.
      <br/>
      <b>ol/layer/Geoportail</b> gets information on the service to handle the layer visibility 
      and source attribution according to the view.
    </p>
    <ul>
      <li>
        ol-ext provide layer capabilities for the main layers. 
      </li>
      <li>
        If you want to access other capabilities :
        <ul>
          <li>
            Asynchronous way: 
            <ul>
              <li>
                Use the <i>ol.layer.Geoportail.getCapabilities()</i> function to get the capabilities 
                from the server for a specific key.
              </li>
              <li>
                Use the <i>ol.layer.Geoportail.loadCapabilities()</i> function to load the capabilities 
                of your key in your code.
              </li>
            </ul>
          </li>
          <li>
            Synchronous way: use the form below to get the code for a layer or 
            a js file with definitions for your key.
          </li>
        </ul>
      </li>
      <li>
        For more information, see <a href="https://geoservices.ign.fr/services-web">IGN 
        Geoservices documentation</a>.
      </li>
    </ul>
    <p>
      You can also <b><a href="./map.geoportail.wmts.html">search within the full list of layer</a></b>.
    </p>
  </div>

	<!-- DIV pour la carte -->
	<div id="map" style="width: 600px; height: 400px;"></div>
	<div class="options">
    Click on the map to get info (photo or INSEE layer only).
	</div>
	<div class="options result">
    <p>
      Use the form below to get code to register a layer or to load your key capabilities as js.
    </p>
    <form onsubmit="loadCapabilities(); return false;">
      <input id="key" 
        type="text" 
        placeholder="your key" 
        onchange="loadCapabilities()"
        style="width: calc(100% - 1.5em); box-sizing: border-box;" 
      /><select id="keys" style="width: 1.5em;" onchange="$('#key').val(this.value); loadCapabilities()">
        <option value="" style="font-style: italic; color: #fff; background-color: #369;">choisir une couche</option>
        <option value="gpf">Free Géoplateforme</option>
        <!-- option value="ign_scan_ws">cartes</option -->
      </select>
    </form>
    <div id="result" style="display: none;">
      <label style="display: block; margin-top:.5em;">Code: <span></span></label>
      <pre id="code"></pre>
      <button id="layer" onclick='addLayer()' style="float: right;">Add layer...</button>
      <hr style="clear:both;" />
      <button type="button" onclick="saveCapabilities()" style="float: right;">Load capabilities</button>
      <button type="button" onclick="loadRegister()" style="float: right;">Load register</button>
      <p style="margin:0; clear:both;">Select a layer</p>
      <ul>
      </ul>
    </div>
	</div>
	
  <script type="text/javascript">
  // Key Capabilities
  ol.layer.Geoportail.register("INSEE.FILOSOFI.NIVEAU.DE.VIE.SECRET", {"layer":"INSEE.FILOSOFI.NIVEAU.DE.VIE.SECRET","theme":"economie","desc":"Niveau de vie des individus, retraité des valeurs extrêmes (les cases hachurées correspondent aux données secrétisées)","server":"https://data.geopf.fr/wmts","bbox":[-63.3725,-21.4756,55.9259,51.3121],"format":"image/png","minZoom":6,"maxZoom":16,"originators":{"Geoservices":{"attribution":"Géoservices","href":"https://geoservices.ign.fr/"}},"queryable":true,"style":"INSEE","tilematrix":"PM","title":"Niveau de vie winsorisé des individus (secret signalé)"});
  ol.layer.Geoportail.register("INSEE.FILOSOFI.ENFANTS.0.17.ANS.SECRET", {"layer":"INSEE.FILOSOFI.ENFANTS.0.17.ANS.SECRET","theme":"economie","desc":"Nombre d’individus âgés de 0 à 17 ans dans la population (les cases hachurées correspondent aux données secrétisées)","server":"https://data.geopf.fr/wmts","bbox":[-63.3725,-21.4756,55.9259,51.3121],"format":"image/png","minZoom":6,"maxZoom":16,"originators":{"Geoservices":{"attribution":"Géoservices","href":"https://geoservices.ign.fr/"}},"queryable":true,"style":"INSEE","tilematrix":"PM","title":"% des 0-17 ans (secret signalé)"});
  ol.layer.Geoportail.register("INSEE.FILOSOFI.PART.PLUS.65.ANS.SECRET", {"layer":"INSEE.FILOSOFI.PART.PLUS.65.ANS.SECRET","theme":"economie","desc":"Nombre d’individus âgés de plus de 65 ans dans la population (les cases hachurées correspondent aux données secrétisées)","server":"https://data.geopf.fr/wmts","bbox":[-63.3725,-21.4756,55.9259,51.3121],"format":"image/png","minZoom":6,"maxZoom":16,"originators":{"Geoservices":{"attribution":"Géoservices","href":"https://geoservices.ign.fr/"}},"queryable":true,"style":"INSEE","tilematrix":"PM","title":"% des plus de 65 ans (secret signalé)"});
  ol.layer.Geoportail.register("INSEE.FILOSOFI.POPULATION", {"layer":"INSEE.FILOSOFI.POPULATION","theme":"economie","desc":"Nombre d'individus par km²","server":"https://data.geopf.fr/wmts","bbox":[-63.3725,-21.4756,55.9259,51.3121],"format":"image/png","minZoom":6,"maxZoom":16,"originators":{"Geoservices":{"attribution":"Géoservices","href":"https://geoservices.ign.fr/"}},"queryable":true,"style":"INSEE","tilematrix":"PM","title":"Densité de population"});
  ol.layer.Geoportail.register("Aire-Parcellaire", {"layer":"Aire-Parcellaire","theme":"parcellaire","desc":"Selon les règlements européens n°110/2008 du 15 janvier 2008, n°1151/2012 du 21 novembre 2012 et n°1308/2013 de l’OCM , le cahier des charges des appellations définit l’aire géographique. Le terme de « délimitation parcellaire » désigne une aire qui repose sur les limites administratives du cadastre (les parcelles) et dont le maillage suffisamment fin permet de tenir compte de variations très localisées des éléments du milieu physique. Elle correspond à l'aire de production de la matière première. Elle est incluse dans l'aire géographique. Données produites par l'Institut National des Origines et la Qualité (INAO)","server":"https://data.geopf.fr/wmts","bbox":[-5.15047,41.3252,9.57054,51.0991],"format":"image/png","minZoom":0,"maxZoom":18,"originators":{"Geoservices":{"attribution":"Géoservices","href":"https://geoservices.ign.fr/"}},"queryable":true,"style":"normal","tilematrix":"PM","title":"Délimitation parcellaire AOC viticole"});
	// The map
	var map = new ol.Map ({
    target: 'map',
    view: new ol.View ({
      zoom: 15,
      center: [261204.43490751847, 6250258.191535994],
      /*
      center: [9.48, 42.738038240088095],
      projection: 'EPSG:4326'
      */
    })
  });

  map.addControl(new ol.control.LayerSwitcher({ trash: true, extent:true }));

  map.addLayer (new ol.layer.Geoportail({
    layer: 'ORTHOIMAGERY.ORTHOPHOTOS',
    permalink: 'ortho',
    className: 'photo',
  }));
  
  map.addLayer (new ol.layer.Geoportail({
    layer: 'GEOGRAPHICALGRIDSYSTEMS.MAPS',
    key: 'ign_scan_ws',
    visible: false
  }))

  map.addLayer (new ol.layer.Geoportail({
    layer: 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2',
    permalink: 'plan',
    className: 'plan',
    visible: true,
    opacity: .5
  }));
  map.addLayer (new ol.layer.Geoportail('CADASTRALPARCELS.PARCELLAIRE_EXPRESS', {
    permalink: 'parcel',
    className: 'parcel',
    visible: false
  }));
  map.addLayer (new ol.layer.Geoportail({
    layer: 'INSEE.FILOSOFI.POPULATION',
    permalink: 'insee',
    className: 'insee',
    visible: false
  }));
  map.addLayer (new ol.layer.Geoportail({
    layer: 'Aire-Parcellaire',
    permalink: 'AOC',
    className: 'AOC',
    title: 'Délimitation AOC viticole',
    opacity: .5,
    visible: false
  }));
  map.addControl(new ol.control.Permalink());

  var vector = new ol.layer.Vector({ title: 'vector', className: 'vector', source: new ol.source.Vector() });
  map.addLayer(vector);

  map.addControl(new ol.control.ScaleLine());

  // Show information on click (getFeatureInfo)
  var popup = new ol.Overlay.Popup();
  map.addOverlay(popup);
  map.on('click', function(e) {
    popup.hide();
    var layers = map.getLayers().getArray();
    for (var i = layers.length-1; i >= 0; i--) {
      l = layers[i];
      var pix = l.getData(e.pixel);
      if (pix && pix[3]) {
        vector.getSource().clear();
        if (l.get('queryable')) {
          var layers = map.getLayers().getArray();
          // Get info in a popup
          if (/INSEE|ORTHOIMAGERY|GEOGRAPHICALGRIDSYSTEMS|PARCELLE/.test(l.get('name'))) {
            l.getSource().getFeatureInfo(
              e.coordinate, 
              map.getView().getResolution(), {
                INFO_FORMAT: 'text/html', // 'application/json',
                callback: function(resp) {
                  if (resp) popup.show(e.coordinate, resp);
                }
              }
            );
          } else {
            // Create new object
            l.getSource().getFeatureInfo(
              e.coordinate, 
              map.getView().getResolution(), {
                INFO_FORMAT: 'application/json',
                callback: function(resp) {
                  if (resp) {
                    resp = JSON.parse(resp);
                    if (resp.features[0]) {
                      var format = new ol.format.GeoJSON();
                      var features = format.readFeatures(resp);
                      vector.getSource().addFeatures(features);
                      console.log(resp.features[0].properties);
                    }
                  }
                }
              }
            );
          }
          break;
        }
      }
    };
  });

  var currentLayer, currentCap = [];
  function addLayer() {
    if (currentLayer) map.addLayer(currentLayer);
  }

  // Save capabilities
  function saveCapabilities() {
    var k = $('#key').val();
    // Export JS
    var js = '// Define global\n'
      + 'if (!window.geoportailConfig) window.geoportailConfig = { capabilities: {} };\n'
      + 'window.geoportailConfig.capabilities[\'default\'] = '
      + (k ? 'window.geoportailConfig.capabilities[\''+k+'\'] = ' : '')
      + '{';
    for (var c in currentCap) {
      if (k !== currentCap[c].key) {
        k = currentCap[c].key;
        js += '\n// --- '+k+'----'
      }
      js += '\n  "'+c+'": '+JSON.stringify(currentCap[c])+',';
    }
    js += '\n};'
    // console.log(currentCap); return;
    var blob = new Blob([js], {type: "text/plain;charset=utf-8"});
    saveAs(blob, 'capabilities.js');
  }

  // Get capapbilities
  function loadCapabilities(k, add) {
    $('#result').hide();
    $('#layer').hide();
    $('#code').text('');
    $('#result label span').text('');
    if (!k) {
      k = $('#key').val();
    }
    $('#keys').val('')
    if (k) {
      if (k==='gpf') k = '';
      ol.layer.Geoportail.getCapabilities(k).then(function(cap) {
        $('#result').show();
        var ul = $('.options ul');
        if (!add) {
          ul.html('');
          currentCap = [];
        }
        Object.keys(cap).forEach(function(l) {
          currentCap[l] = cap[l];
          var ck = cap[l];
          $('<li>').text(l)
            .click(function() {
              $('#code').text(
                'ol.layer.Geoportail.register('
                + '"' + l + '", '
                + JSON.stringify(ck)
                + ');\n'
                + 'var layer = new ol.layer.Geoportail({ layer: \''+l+'\' });');
              $('#layer').show();
              $('#result label span').text(l);
              ol.layer.Geoportail.register(l, ck);
              currentLayer = new ol.layer.Geoportail({
                layer: l,
                projection: map.getView().getProjection()
              });
            })
            .appendTo(ul)
        });
      }).catch(function(e) {
        alert ('Error while loading capabilities for key "'+k+'".');
      });
    }
  }

  // Load js register
  function loadRegister() {
    var register = '';
    var k = $('#key').val();
    Object.keys(currentCap).forEach(function(l) {
      var ck = currentCap[l];
      if (k !== ck.key) {
        k = ck.key;
        register += '// --- '+k+' ----\n'
      }
      register += 'ol.layer.Geoportail.register('
        + '"' + l + '", '
        + JSON.stringify(ck)
        + ');\n';
    });
    // console.log(register); return;
    var blob = new Blob([register], {type: "text/plain;charset=utf-8"});
    saveAs(blob, 'register.js');
  }

  // Save Vector layer
  function save() {
    var format = new ol.format.GeoJSON();
    var features = vector.getSource().getFeatures();
		var data = format.writeFeatures(features, {
			dataProjection: 'EPSG:4326',
			featureProjection: map.getView().getProjection()
    });
		var blob = new Blob([data], {type: "text/plain;charset=utf-8"});
		saveAs(blob, "map.geojson");
  }

	</script>
</body>
</html>